home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / mach / sun3.md / machMigrate.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  8KB  |  278 lines

  1. /* 
  2.  * machMigrate.c --
  3.  *
  4.  *         Machine dependent code to support process migration.  These routines
  5.  *         encapsulate and deencapsulate the machine-dependent state of a
  6.  *    process and set up the state of the process on its new machine.
  7.  *
  8.  * Copyright 1988 Regents of the University of California
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software and its documentation for any purpose and without
  11.  * fee is hereby granted, provided that the above copyright
  12.  * notice appear in all copies.  The University of California
  13.  * makes no representations about the suitability of this
  14.  * software for any purpose.  It is provided "as is" without
  15.  * express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/mach/sun3.md/machMigrate.c,v 9.2 91/09/10 18:17:19 rab Exp $ SPRITE (Berkeley)";
  20. #endif /* not lint */
  21.  
  22. #include "sprite.h"
  23. #include "stdio.h"
  24. #include "machConst.h"
  25. #include "machInt.h"
  26. #include "mach.h"
  27. #include "machMon.h"
  28. #include "sched.h"
  29. #include "procMigrate.h"
  30.  
  31. /*
  32.  * The information that is transferred between two machines.
  33.  */
  34. typedef struct {
  35.     Mach_UserState userState;        /* The contiguous machine-dependent
  36.                      * user state. */
  37.     int    pc;                /* PC at which to resume execution. */
  38. } MigratedState;
  39.  
  40.  
  41. /*
  42.  * ----------------------------------------------------------------------------
  43.  *
  44.  * Mach_EncapState --
  45.  *
  46.  *    Copy the machine-dependent information for a process into
  47.  *    a buffer.  The buffer passed to the routine must contain space for
  48.  *    a MigratedState structure, the size of which is accessible via 
  49.  *    another procedure.  
  50.  *
  51.  * Results:
  52.  *      SUCCESS.
  53.  *    The buffer is filled with the user state and PC of the process.
  54.  *
  55.  * Side effects:
  56.  *    None.
  57.  *
  58.  * ----------------------------------------------------------------------------
  59.  */
  60. /* ARGSUSED */
  61. ReturnStatus
  62. Mach_EncapState(procPtr, hostID, infoPtr, buffer)
  63.     register Proc_ControlBlock     *procPtr;  /* The process being migrated */
  64.     int hostID;                   /* host to which it migrates */
  65.     Proc_EncapInfo *infoPtr;           /* area w/ information about
  66.                         * encapsulated state */
  67.     Address buffer;               /* Pointer to allocated buffer */
  68. {
  69.     Mach_State *machStatePtr = procPtr->machStatePtr;
  70.     MigratedState *migPtr = (MigratedState *) buffer;
  71.  
  72.     bcopy((Address) &machStatePtr->userState, (Address) &migPtr->userState,
  73.         sizeof(Mach_UserState));
  74.     migPtr->pc = machStatePtr->userState.excStackPtr->pc;
  75.     return(SUCCESS);
  76. }    
  77.     
  78.  
  79. /*
  80.  * ----------------------------------------------------------------------------
  81.  *
  82.  * Mach_DeencapState --
  83.  *
  84.  *    Copy the machine-dependent information for a process from
  85.  *    a buffer.  The buffer passed to the routine must contain
  86.  *    a MigratedState structure created by Mach_EncapState on the
  87.  *    machine starting a migration.  
  88.  *
  89.  * Results:
  90.  *    The user state and PC of the process are initialized from the
  91.  *    encapsulated information, and the other standard process
  92.  *    initialization operations are performed (by the general initialization
  93.  *    procedure).  The status from that procedure is returned.
  94.  *
  95.  * Side effects:
  96.  *    None.
  97.  *
  98.  * ----------------------------------------------------------------------------
  99.  */
  100. /* ARGSUSED */
  101. ReturnStatus
  102. Mach_DeencapState(procPtr, infoPtr, buffer)
  103.     register Proc_ControlBlock     *procPtr; /* The process being migrated */
  104.     Proc_EncapInfo *infoPtr;          /* information about the buffer */
  105.     Address buffer;              /* buffer containing data */
  106. {
  107.     MigratedState *migPtr = (MigratedState *) buffer;
  108.     ReturnStatus status;
  109.  
  110.     if (infoPtr->size != sizeof(MigratedState)) {
  111.     if (proc_MigDebugLevel > 0) {
  112.         printf("Mach_DeencapState: warning: host %d tried to migrate",
  113.         procPtr->peerHostID);
  114.         printf(" onto this host with wrong structure size.");
  115.         printf("  Ours is %d, theirs is %d.\n",
  116.         sizeof(MigratedState), infoPtr->size);
  117.     }
  118.     return(PROC_MIGRATION_REFUSED);
  119.     }
  120.  
  121. #ifdef sun3
  122.     if (migPtr->userState.trapFpuState.version != 0) {
  123.     if (mach68881Present == FALSE) {
  124.         /*
  125.          *  This machine has no fpu, and this process needs one.
  126.          *  So we can't accept it.
  127.          */
  128.         printf("Mach_DeencapState: warning: host %d tried to migrate",
  129.         procPtr->peerHostID);
  130.         printf(" a process that uses the fpu.  This host has no fpu.\n");
  131.         return PROC_MIGRATION_REFUSED;
  132.     }
  133.     if (migPtr->userState.trapFpuState.state != MACH_68881_IDLE_STATE) {
  134.         printf("Mach_DeencapState: warning: host %d tried to migrate",
  135.         procPtr->peerHostID);
  136.         printf(" a process with a non-idle fpu onto this host.  ");
  137.         printf("The fpu was in state 0x%02x\n",
  138.         migPtr->userState.trapFpuState.state);
  139.         return PROC_MIGRATION_REFUSED;
  140.     }
  141.     if (migPtr->userState.trapFpuState.version != mach68881Version) {
  142.         /*
  143.          *  The sending host has a different version of the
  144.          *  mc68881 fpu.  The state frames are incompatible
  145.          *  between versions.  But since it is in idle state
  146.          *  we can just use a generic idle state frame, rather
  147.          *  than the one we were sent.
  148.          */
  149.         migPtr->userState.trapFpuState = mach68881IdleState;
  150.     }
  151.     }
  152. #endif
  153.  
  154.     /*
  155.      * Get rid of the process's old machine-dependent state if it exists.
  156.      */
  157.     if (procPtr->machStatePtr != (Mach_State *) NIL) {
  158.     Mach_FreeState(procPtr);
  159.     }
  160.  
  161.     /*
  162.      * This procedure relies on the fact that Mach_SetupNewState
  163.      * only looks at the Mach_UserState part of the Mach_State structure
  164.      * it is given.  Therefore, we can coerce the pointer to a Mach_State
  165.      * pointer and give it to Mach_UserState to get registers & such.
  166.      */
  167.  
  168.     status = Mach_SetupNewState(procPtr, (Mach_State *) &migPtr->userState,
  169.                 Proc_ResumeMigProc, (Address)migPtr->pc, TRUE);
  170.     return(status);
  171. }    
  172.     
  173.  
  174.  
  175. /*
  176.  * ----------------------------------------------------------------------------
  177.  *
  178.  * Mach_GetEncapSize --
  179.  *
  180.  *    Return the size of the encapsulated machine-dependent data.
  181.  *
  182.  * Results:
  183.  *    SUCCESS is returned directly; the size of the encapsulated state
  184.  *    is returned in infoPtr->size.
  185.  *
  186.  * Side effects:
  187.  *    None.
  188.  *
  189.  * ----------------------------------------------------------------------------
  190.  *
  191.  */
  192.  
  193. /* ARGSUSED */
  194. ReturnStatus
  195. Mach_GetEncapSize(procPtr, hostID, infoPtr)
  196.     Proc_ControlBlock *procPtr;            /* process being migrated */
  197.     int hostID;                    /* host to which it migrates */
  198.     Proc_EncapInfo *infoPtr;            /* area w/ information about
  199.                          * encapsulated state */
  200. {
  201.     infoPtr->size = sizeof(MigratedState);
  202.     return(SUCCESS);
  203. }
  204.  
  205.  
  206. /*
  207.  * ----------------------------------------------------------------------------
  208.  *
  209.  * Mach_CanMigrate --
  210.  *
  211.  *    Indicate whether a process's trapstack is in a form suitable for
  212.  *    starting a migration.
  213.  *
  214.  * Results:
  215.  *    TRUE if we can migrate using this trapstack, FALSE otherwise.
  216.  *
  217.  * Side effects:
  218.  *    None.
  219.  *
  220.  * ----------------------------------------------------------------------------
  221.  */
  222. Boolean
  223. Mach_CanMigrate(procPtr)
  224.     Proc_ControlBlock *procPtr;        /* pointer to process to check */
  225. {
  226.     Boolean okay;
  227.  
  228.     okay = TRUE;
  229.  
  230. #ifdef sun3
  231.     /*
  232.      *  If the floating point state is busy, that means that a
  233.      *  floating point instruction is suspended, waiting to be
  234.      *  restarted.  It cannot be restarted on a machine with another
  235.      *  version of the chip, since the microcode is incompatible between
  236.      *  revisions.  So we will delay the migration until the instruction
  237.      *  completes.
  238.      */
  239.     if (procPtr->machStatePtr->userState.trapFpuState.state >=
  240.         MACH_68881_BUSY_STATE) {
  241.     okay = FALSE;
  242.     }
  243. #endif
  244.  
  245.     if (proc_MigDebugLevel > 4) {
  246.     printf("Mach_CanMigrate called. PC %x, stackFormat %x, returning %d.\n",
  247.            procPtr->machStatePtr->userState.excStackPtr->pc, okay);
  248.     }
  249.     return(okay);
  250. }    
  251.  
  252.  
  253. /*
  254.  *----------------------------------------------------------------------
  255.  *
  256.  * Mach_GetLastSyscall --
  257.  *
  258.  *    Return the number of the last system call performed for the current
  259.  *    process.
  260.  *
  261.  * Results:
  262.  *    The system call number is returned.
  263.  *
  264.  * Side effects:
  265.  *    None.
  266.  *
  267.  *----------------------------------------------------------------------
  268.  */
  269.  
  270. int
  271. Mach_GetLastSyscall()
  272. {
  273.     Proc_ControlBlock *procPtr;        /* pointer to process to check */
  274.  
  275.     procPtr = Proc_GetCurrentProc();
  276.     return(procPtr->machStatePtr->userState.lastSysCall);
  277. }
  278.